#include "Rp2Controller.h"
#include "Rp2Math.h"

using namespace Rp2;

RP2_IMPLEMENT_RTTI(Rp2, Controller, Object);
RP2_IMPLEMENT_DEFAULT_NAME_ID(Controller, Object);

const char* Controller::ms_aacRepeatType[Controller::RT_QUANTITY] =
{
    "RT_CLAMP",
    "RT_WRAP",
    "RT_CYCLE"
};

//---------------------------------------------------------------------------------------------------
Controller::Controller()
{
    m_pkObject = 0;
    Repeat = RT_CLAMP;
    MinTime = 0.0;
    MaxTime = 0.0;
    Phase = 0.0;
    Frequency = 1.0;
    Active = true;
    m_dLastAppTime = -DBL_MAX;
}
//---------------------------------------------------------------------------------------------------
Controller::~Controller()
{
}
//---------------------------------------------------------------------------------------------------
double Controller::GetControlTime(double dAppTime)
{
	double dCtrlTime = Frequency * dAppTime + Phase;

    if (Repeat == RT_CLAMP)
    {
        if (dCtrlTime < MinTime)
        {
            return MinTime;
        }
        if (dCtrlTime > MaxTime)
        {
            return MaxTime;
        }
        return dCtrlTime;
    }

    double dRange = MaxTime - MinTime;
    if (dRange > 0.0)
    {
        double dMultiples = (dCtrlTime - MinTime)/dRange;
        double dIntTime = floor(dMultiples);
        double dFrcTime = dMultiples - dIntTime;
        if (Repeat == RT_WRAP)
        {
            return MinTime + dFrcTime*dRange;
        }

        // Repeat == RT_CYCLE
        if (((int)dIntTime) & 1)
        {
            // backward time
            return MaxTime - dFrcTime*dRange;
        }
        else
        {
            // forward time
            return MinTime + dFrcTime*dRange;
        }
    }
    else
    {
        return MinTime;
    }	
}
//---------------------------------------------------------------------------------------------------
bool Controller::Update(double dAppTime)
{
    if (Active
    &&  (dAppTime == -Mathd::MAX_REAL || dAppTime != m_dLastAppTime))
    {
        m_dLastAppTime = dAppTime;
        return true;
    }
    return false;
}
//---------------------------------------------------------------------------------------------------